home *** CD-ROM | disk | FTP | other *** search
- name msxgen
- ; File MSXGEN.ASM
- include mssdef.h
- ; Copyright (C) 1982,1991, Trustees of Columbia University in the
- ; City of New York. Permission is granted to any individual or
- ; institution to use, copy, or redistribute this software as long as
- ; it is not sold for profit and this copyright notice is retained.
- ; Generic MS DOS Kermit module, does i/o via DOS calls.
- ; Use with file MSUGEN.ASM (Generic keyboard translator)
- ; Edit history
- ; 8 Sept 1991 version 3.11
- ; Last edit 8 Sept 1991
- ;
- ; Note: the biggest difficulty using this Generic Kermit is loss of one
- ; or two incoming characters when the screen must scroll. IBM PC's and
- ; relatives do this. If possible, replace the DOS screen write with faster
- ; calls specific to your system. Port i/o is polled through DOS.
-
- public serini, serrst, clrbuf, outchr, coms, vts, vtstat, dodel
- public ctlu, cmblnk, locate, lclini, prtchr, baudst, clearl
- public getbaud, beep, trnprs, pcwait, termtb, trnmod, setnbios
- public count, xofsnt, puthlp, putmod, clrmod, poscur
- public sendbr, sendbl, term, machnam, setktab, setkhlp, showkey
- public ihosts, ihostr, dtrlow, serhng, dumpscr, comptab
- public chrout, cstatus, cquit, cquery, chang ; kbd action verbs
- public snull, kdos, klogof, klogon, shomodem, getmodem, mdmhand
- public portval, bdtab, setchtab, extmacro, vtmacname, vtmaclen
- public fcsrtype, parmsk, flowon, flowoff, peekcom
- public sescur, sesdisp
-
- false equ 0
- true equ 1
- instat equ 6
- prtscr equ 1 ; screen printing active
-
- data segment
- extrn flags:byte, trans:byte, comand:byte, dmpname:byte
- extrn npages:word, kbdflg:byte, rxtable:byte, rdbuf:byte
- extrn prnhand:word, taklev:byte, takadr:word, mcctab:byte
- extrn param:word, nparam:word
- machnam db 'Generic$'
- erms41 db cr,lf,'?Warning: Cannot open COM port$'
- erms50 db cr,lf,'Error reading from device$'
- hnd1 db cr,lf,'Enter a file handle. Check your DOS manual if you are '
- db cr,lf,'not certain what value to supply (generally 3).$'
- hnd2 db 'Handle: ',0
- hnderr db cr,lf,'Warning: Handle not known.'
- deverr db cr,lf,'Any routine using the communications port will'
- db cr,lf,'probably not work.$'
- hndhlp db cr,lf,'A one or two digit file handle $'
- devhlp db cr,lf,'Name for your systems auxillary port $'
- badbd db cr,lf,'Unimplemented baud rate$'
- noimp db cr,lf,'Command not implemented.$'
- hngmsg db cr,lf,' The phone should have hungup.',cr,lf,'$'
- hnghlp db cr,lf,' The modem control lines DTR and RTS for the current'
- db ' port are forced low (off)'
- db cr,lf,' to hangup the phone. Normally, Kermit leaves them'
- db ' high (on) when it exits.'
- db cr,lf,'$'
- msmsg1 db cr,lf,' Communications port is not ready.$'
- msmsg2 db cr,lf,' Communications port is ready.$'
-
- shkmsg db 'Not implemented'
- shklen equ $-shkmsg
- setktab db 0
- setkhlp db 0
- anspflg db 0 ; printing active status
- vtmacname dw 0 ; pointer to selected macro name
- vtmaclen dw 0
- sescur dw 0
- crlf db cr,lf,'$'
- delstr db BS,BS,' ',BS,BS,'$' ; Delete string
- ; If delete code moves cursor then BS over code, BS over bad char, space
- ; over both to erase from screen, BS twice to restore cursor position.
- argadr dw ? ; address of arg blk from msster.asm
- parmsk db 0ffh ; 8/7 bit parity mask, for reception
- flowoff db 0 ; flow-off char, Xoff or null (if no flow)
- flowon db 0 ; flow-on char, Xon or null
- captrtn dw 0 ; routine to call for captured output
- xofsnt db 0 ; Say if we sent an XOFF
- xofrcv db 0 ; Say if we received an XOFF
- count dw 0 ; Number of chars in int buffer
- fairness dw 0
- mdmhand db 0 ; Modem status register, current
- prthnd dw 0 ; Port handle
- prttab dw com1,com2
- com1 db 'COM1',0
- com2 db 'COM2',0
- temp dw 0
- prtstr db 20 dup(0) ; Name of auxiliary device
-
- portmax equ 4 ; number of predefined ports
-
- port1 prtinfo <0FFFH,0,defpar,1,0,defhand,floxon>
- port2 prtinfo <0FFFH,0,defpar,1,0,defhand,floxon>
- port3 prtinfo <0FFFH,0,defpar,1,0,defhand,floxon>
- port4 prtinfo <0FFFH,0,defpar,1,0,defhand,floxon>
- rept portmax-4
- prtinfo <0FFFH,0,defpar,1,0,defhand,floxon>
- endm
- portval dw port1 ; Default is to use port 1
-
- ; Entries for choosing communications port
- comptab db 6 ; Number of options
- mkeyw '1',1
- mkeyw '2',2
- mkeyw 'COM1',1
- mkeyw 'COM2',2
- mkeyw 'Device',3
- mkeyw 'File-handle',4
-
- setchtab db 1 ; Set File Character-Set table
- mkeyw 'CP437',437 ; hardware default Code Page
-
- bdtab db 0 ; baud rate table, number of entries
-
- ourarg termarg <>
-
- termtb db tttypes ; entries for Status, not Set
- mkeyw 'Heath-19',ttheath
- mkeyw 'none',ttgenrc
- mkeyw 'Tek4014',tttek
- mkeyw 'VT102',ttvt100
- mkeyw 'VT52',ttvt52
-
- oldsp dw 0 ; offset to longjmp to for i/o failure
- endconptr dw offset endcon,seg endcon ; FAR pointer
- vtmacroptr dw offset vtmacro,seg vtmacro ; FAR pointer
- data ends
-
- code1 segment
- ; Control text cursor. AL = 0 for off, 1 for on (nominally underline)
- fcsrtype proc far
- ret ; can't do this from DOS
- fcsrtype endp
- code1 ends
-
- code segment
- extrn comnd:near, dopar:near, atoi:near, prompt:near
- extrn msuinit:near, keybd:near, pntchr:near, pntflsh:near
- extrn dec2di:near
- assume cs:code, ds:data, es:nothing
-
- ; Clear the input buffer. This throws away all the characters in the
- ; serial interrupt buffer. This is particularly important when
- ; talking to servers, since NAKs can accumulate in the buffer.
- ; Do nothing since we are not interrupt driven. Returns normally.
-
- CLRBUF PROC NEAR
- cmp prthnd,0 ; got a port handle yet?
- jne clrbu1 ; ne = yes
- ret ; else just return
- clrbu1: call prtchr ; read from comms port
- jnc clrbu1 ; nc = char available
- ret ; no data
- CLRBUF ENDP
-
- ; Clear to the end of the current line. Returns normally.
-
- CLEARL PROC NEAR
- push ax
- push dx
- mov ah,prstr
- mov dx,offset crlf
- int dos
- pop dx
- pop ax
- ret
- CLEARL ENDP
-
- shomodem proc near
- mov ah,cmeol ; get a confirm
- call comnd
- jc shmodx ; c = no confirm
- cmp prthnd,0 ; got a handle yet?
- jne shmod0 ; ne = yes, just go on
- call opnprt ; else 'open' the port
- shmod0: mov dx,offset msmsg1 ; say port is not ready
- mov bx,prthnd
- mov al,7 ; output status command
- mov ah,ioctl ; ask DOS to look for us
- int dos
- jc shmod1 ; c = call failed, device not ready
- or al,al
- jz shmod1 ; z = not ready
- mov dx,offset msmsg2 ; say port is ready
- shmod1: mov ah,prstr
- int dos
- clc
- shmodx: ret
- shomodem endp
-
- getmodem proc near
- mov al,0
- clc
- ret
- getmodem endp
-
- ; Put the char in AH to the serial port. This assumes the port has been
- ; initialized. Returns carry clear if success, else carry set if the
- ; character cannot be written.
-
- OUTCHR PROC NEAR
- push cx ; save regs
- or ah,ah ; sending a null?
- jz outch2 ; z = yes
- xor cx,cx ; clear counter
- cmp ah,flowoff ; sending xoff?
- jne outch1 ; ne = no
- mov xofsnt,false ; supress xon from chkxon buffer routine
- outch1: cmp xofrcv,true ; are we being held?
- jne outch2 ; ne = no, it's OK to go on
- loop outch1 ; held, try for a while
- mov xofrcv,false ; timed out, force it off and fall thru
- outch2: push dx ; save register
- mov al,ah ; parity routine works on AL
- call dopar ; set parity appropriately
- mov byte ptr temp,al ; put data there
- cmp prthnd,0 ; got a handle yet?
- jne outch3 ; ne = yes
- call opnprt ; else 'open' the port
- outch3: push bx
- mov bx,prthnd ; port handle
- mov cx,1 ; one byte to write
- mov dx,offset temp ; place where data will be found
- mov ah,write2 ; write to file/device
- int dos
- pop bx
- pop dx
- pop cx
- clc
- ret
- OUTCHR ENDP
-
- ; This routine blanks the screen. Returns normally.
-
- CMBLNK PROC NEAR
- push ax ; save some registers
- push dx
- mov ah,prstr
- mov dx,offset crlf ; carriage return plus line feed
- pop dx
- pop ax
- ret
- CMBLNK ENDP
-
- ; Homes the cursor. Returns normally.
-
- LOCATE PROC NEAR
- mov dx,0 ; Go to top left corner of screen
- jmp poscur
- LOCATE ENDP
-
- ; Write a line at the bottom of the screen
- ; the line is passed in dx, terminated by a $. Returns normally.
- putmod proc near
- push dx ; preserve message
- mov dx,1800h ; now address line 24
- call poscur
- pop dx ; get message back
- mov ah,prstr
- int dos ; write it out
- ret ; and return
- putmod endp
-
- ; clear the mode line written by putmod. Returns normally.
- clrmod proc near
- mov dx,1800h
- call poscur ; Go to bottom row
- call clearl ; Clear to end of line
- ret
- clrmod endp
-
- ; Put a help message on the screen.
- ; Pass the message in ax, terminated by a null. Returns normally.
- puthlp proc near
- push dx ; save regs
- push si
- push ax ; preserve this
- mov ah,prstr
- mov dx,offset crlf
- int dos
- pop si ; point to string again
- cld
- puthl3: lodsb ; get a byte
- cmp al,0 ; end of string?
- je puthl4 ; yes, stop
- mov dl,al
- mov ah,dconio
- int dos ; else write to screen
- jmp puthl3 ; and keep going
- puthl4: mov ah,prstr
- mov dx,offset crlf
- int dos
- pop si
- pop dx
- ret
- puthlp endp
-
- ; Set the baud rate for the current port, based on the value
- ; in the portinfo structure. Returns normally.
-
- BAUDST PROC NEAR
- mov ah,prstr
- mov dx,offset noimp ; Say it's not implemented
- int dos
- push bx ; save reg
- mov bx,portval
- mov [bx].baud,0FFFFH ; So it's not a recognized value
- pop bx
- ret
- BAUDST ENDP
-
- ; Get the current baud rate from the serial card and set it
- ; in the portinfo structure for the current port. Returns normally.
- ; This is used during initialization.
-
- GETBAUD PROC NEAR
- stc
- ret ; Can't do this
- GETBAUD ENDP
-
- ; Use for DOS 2.0 and above. Check the port status. If no data, return
- ; carry set; else read a char into AL and return carry clear.
- ; Note added by [jrd]: The test for char-at-input-port is int 21h function
- ; 44h (ioctl) sub function 6 (get input status). On many systems an FFH will
- ; be reported (meaning Ready) even though no char is available; the Ready
- ; indication is misleading. In such cases the system will wait for a char
- ; and will appear to be hung. A preferrable method is to use the ROM Bios
- ; call int 14H function 3 (get port status) and if the lsb of the returned
- ; 8 bits in AH is 1 then a char is availble at the port; this assumes that
- ; the machine emulates this ROM Bios operation.
- ; Lastly, if the current code is used and the system hangs then reboot
- ; and say ECHO Hello >COM1 before running Kermit; this should make MSDOS
- ; truely aware of the port's actual status. Dark grey magic. Good luck! [jrd]
- PRTCHR PROC NEAR
- push bx
- push cx
- cmp prthnd,0 ; got a handle yet?
- jne prtch0 ; ne = yes
- call opnprt ; else 'open' the port
- prtch0: call chkxon
- mov bx,prthnd
- mov al,instat ; input status command
- mov ah,ioctl ; see note above
- int dos
- jc prtch4 ; c = call failed, device not ready
- or al,al
- jz prtch4 ; not ready
- mov bx,prthnd ; the file handle
- mov ah,readf2 ; read file/device
- mov cx,1 ; want just one character
- mov dx,offset rdbuf ; where to store it
- int dos
- jnc prtch1 ; nc = no error
- cmp al,5 ; Error condition
- je prt3x
- cmp al,6 ; Error condition
- je prt3x
- jmp prtch4 ; else report no char present
- prtch1: mov dx,ax ; needed to obey rules
- or ax,ax ; reading from end of file?
- jz prtch4 ; z = yes
- mov al,rdbuf ; recover char
- prtch3: pop cx
- pop bx
- clc
- ret ; return success (char is in al)
- prt3x: mov ah,prstr
- mov dx,offset erms50
- int dos
- prtch4: pop cx
- pop bx
- stc ; no chars
- ret
- PRTCHR ENDP
-
- ; Examine incoming communications stream for a packet SOP character.
- ; Return CX= count of bytes starting at the SOP character (includes SOP)
- ; and carry clear. Return CX = 0 and carry set if SOP is not present.
- ; Destroys AL.
- peekcom proc far
- xor cx,cx ; return count of zero
- stc ; say no data
- ret
- peekcom endp
-
- ; Local routine to see if we have to transmit an xon
- chkxon proc near
- push bx
- mov bx,portval
- cmp [bx].floflg,0 ; doing flow control?
- je chkxo1 ; no, skip all this
- cmp xofsnt,false ; have we sent an xoff?
- je chkxo1 ; no, forget it
- mov ax,[bx].flowc ; ah gets xon
- call outchr ; send it
- mov xofsnt,false ; remember we've sent the xon
- chkxo1: pop bx ; restore register
- ret ; and return
- chkxon endp
-
- ; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the
- ; cycle of clear input buffer, wait 1 second, test if buffer empty then exit
- ; else repeat cycle. Requires that the port be initialized before hand.
- ; Ihosts is used by the local send-file routine just after initializing
- ; the serial port.
- ; 22 March 1986 [jrd]
-
- IHOSTS PROC NEAR
- push ax ; save the registers
- push bx
- push cx
- push dx
- mov bx,portval ; port indicator
- mov ax,[bx].flowc ; put Go-ahead flow control char in ah
- or ah,ah ; don't send null if flow = none
- jz ihosts1 ; z = null
- call outchr ; send it (release Host's output queue)
- ihosts1:call clrbuf ; clear out interrupt buffer
- call prtchr ; check for char at port
- jnc ihosts1 ; nc=have a char in al, repeat wait/read cycle
- pop dx ; empty buffer. we are done here
- pop cx
- pop bx
- pop ax
- ret
- IHOSTS ENDP
-
- ; IHOSTR - initialize the remote host for our reception of a file by
- ; sending the flow-on character (XON typically) to release any held
- ; data. Called by receive-file code just after initializing the serial
- ; port. 22 March 1986 [jrd]
- IHOSTR PROC NEAR
- push ax ; save regs
- push bx
- push cx
- mov bx,portval ; port indicator
- mov ax,[bx].flowc ; put Go-ahead flow control char in ah
- or ah,ah ; don't send null if flow = null
- jz ihostr1 ; z = null
- call outchr ; send it (release Host's output queue)
- ihostr1:pop cx
- pop bx
- pop ax
- ret
- IHOSTR ENDP
-
- DTRLOW PROC NEAR ; Global proc to Hangup the Phone by making
- ; DTR and RTS low
- mov ah,cmline ; allow text to be able to display help
- mov bx,offset rdbuf ; dummy buffer
- mov dx,offset hnghlp ; help message
- call comnd ; get a confirm
- jc dtrlowx
- ; not yet imp. call serhng ; drop DTR and RTS
- mov ah,prstr ; give a nice message
- ; not yet imp. mov dx,offset hngmsg
- mov dx,offset noimp ; for now
- int dos
- clc
- dtrlowx:ret
- DTRLOW ENDP
-
- ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
- ; to terminate the connection. 29 March 1986 [jrd]
- ; Calling this twice without intervening calls to serini should be harmless.
- ; Returns normally.
- ; SERHNG is Not Yet Implemented.
-
- SERHNG PROC NEAR
- clc
- ret
- SERHNG ENDP
-
- ; Wait for the # of milliseconds in ax, for non-IBM compatibles.
- ; Based on 4.77 Mhz 8088 processor speeds.
- ; Thanks to Bernie Eiben for this one.
- pcwait proc near
- mov cx,240 ; inner loop counter for 1 millisecond
- pcwai1: sub cx,1 ; inner loop takes 20 clock cycles
- jnz pcwai1
- dec ax ; outer loop counter
- jnz pcwait ; wait another millisecond
- ret
- pcwait endp
-
-
- ; Send a break out the current serial port. Returns normally.
- SENDBR PROC NEAR ; Normal Break
- clc
- ret
- SENDBR ENDP
- SENDBL PROC NEAR ; Long Break
- clc
- ret
- SENDBL ENDP
-
- ; Position the cursor according to contents of DX:
- ; DH contains row, DL contains column. Returns normally.
- POSCUR PROC NEAR
- clc
- ret
- POSCUR ENDP
-
- ; Delete a character from the terminal. This works by printing
- ; backspaces and spaces. Returns normally.
-
- DODEL PROC NEAR
- mov ah,prstr
- mov dx,offset delstr ; Erase character
- int dos
- ret
- DODEL ENDP
-
- ; Move the cursor to the left margin, then clear to end of line.
- ; Returns normally.
-
- CTLU PROC NEAR
- push ax
- push cx
- push dx
- mov ah,conout
- mov dl,cr ; cursor to left margin
- int dos
- mov cx,79
- mov dl,' ' ; send 79 spaces to clear line
- ctlu1: int dos
- loop ctlu1
- mov dl,cr ; cursor to left margin again
- int dos
- pop dx
- pop cx
- pop ax
- ret
- CTLU ENDP
-
- ; Set the current port.
-
- COMS PROC NEAR
- mov dx,offset comptab ; the table to examine
- xor bx,bx ; use keywords as help
- mov ah,cmkey ; parse keyword from comptab
- call comnd
- jc comsx ; c = no match
- cmp bl,3 ; set device name?
- je coms3 ; e = yes, go get name
- jbe coms1a ; be = 1 or 2
- jmp coms4 ; a = pick up file handle
- coms1a: push bx
- mov ah,cmeol
- call comnd
- pop bx
- jc comsx ; failure
- mov flags.comflg,bl ; set the comm port flag
- cmp bl,1 ; using Com 1?
- jne coms2 ; ne = no
- mov portval,offset port1
- ret
- coms2: cmp flags.comflg,2 ; using Com2?
- jne coms3 ; ne = no
- mov portval,offset port2
- clc
- comsx: ret
- coms3: mov ah,cmword ; parse string, returns asciiz string
- mov dx,offset prtstr ; put name here
- mov bx,offset devhlp ; help message if question mark
- call comnd
- jc comsx ; c = error
- mov ah,cmeol
- call comnd
- jc comsx
- mov dx,offset prtstr ; point to string
- mov ah,open2 ; open port as a file
- mov al,2 ; for reading and writing
- int dos
- jc coms31 ; c = failure
- mov portval,offset port3 ; port info structure
- mov flags.comflg,3 ; set port ident
- jmp short coms32 ; success
- coms31: mov ah,prstr
- mov dx,offset erms41
- int dos
- mov dx,offset deverr
- int dos
- clc
- ret
- coms32: mov prthnd,ax ; save handle
- mov ah,ioctl
- mov al,00h ; get device info
- xor dx,dx
- mov bx,prthnd ; port's handle
- int dos
- jc coms41 ; c = error
- or dl,20h ; set binary mode in device info
- mov dh,0
- mov ah,ioctl
- mov al,01h ; set device info
- int dos
- jc coms41 ; c = error
- ret
- coms4: mov ah,cmword
- mov dx,offset rdbuf ; where to put input
- mov bx,offset hndhlp ; in case user wants help
- call comnd
- jc coms42
- push ax
- mov ah,cmeol
- call comnd
- pop ax
- jc coms42 ; failure
- mov si,offset rdbuf
- call atoi ; convert to real number in ax
- jc coms42 ; c = failure
- mov portval,offset port4 ; port info structure
- mov flags.comflg,4 ; set port ident
- jmp coms32 ; go complete processing
- coms41: mov ah,prstr ; else, issue a warning
- mov dx,offset hnderr
- int dos
- clc
- coms42: ret
- COMS ENDP
-
- ; Set heath emulation on/off.
-
- VTS PROC NEAR
- jmp notimp ; not implemented
- VTS ENDP
-
-
- VTSTAT PROC NEAR ; for Status display
- ret ; no emulator status to display
- VTSTAT ENDP
-
- ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
- ; Default filename is Kermit.scn; actual file can be a device too. Filename
- ; is determined by mssset and is passed as pointer dmpname.
-
- DUMPSCR PROC NEAR ; Dumps screen contents to a file. Just Beeps here
- call beep
- clc
- ret
- DUMPSCR ENDP
-
- notimp: mov ah,prstr
- mov dx,offset noimp
- int dos
- stc
- ret
-
- ; Initialize variables to values used by the generic MS DOS version.
-
- lclini: mov flags.vtflg,0 ; don't do terminal emulation
- mov prthnd,0 ; no handle yet
- mov flags.remflg,dserial ; set serial display mode
- ;; call opnprt ; get file handle for comm port
- call msuinit ; declare keyboard translator present
- ret
-
- ; Get a file handle for the communications port. Use DOS call to get the
- ; next available handle. If it fails, ask user what value to use (there
- ; should be a predefined handle for the port, generally 3). The open
- ; will fail if the system uses names other than "COM1" or "COM2".
- opnprt: mov al,flags.comflg
- dec al ; com1 is 1, com2 is 2, etc
- xor ah,ah
- push si
- mov si,ax
- shl si,1 ; double index
- mov dx,prttab[si] ; table of port names
- pop si
- mov ah,open2 ; open file/device
- mov al,2 ; for reading/writing
- int dos
- jnc opnpr2 ; nc = no error so far
- mov ah,prstr ; It didn't like the string
- mov dx,offset erms41
- int dos
- mov dx,offset hnd1
- int dos
- mov dx,offset hnd2 ; ask user for the handle
- call prompt
- mov ah,cmline
- mov bx,offset rdbuf ; where to put input
- mov dx,offset hndhlp ; in case user wants help
- call comnd
- jc opnpr1 ; c = error
- mov si,offset rdbuf
- xchg ah,al ; count to ah
- call atoi ; convert to real number
- jc opnpr1 ; c = error
- mov prthnd,ax ; value returned in AX
- clc ; carry clear for success
- opnpr1: ret
- opnpr2: mov prthnd,ax ; call succeeded
- mov ah,ioctl
- mov al,00h ; get device info
- xor dx,dx
- mov bx,prthnd ; port's handle
- int dos
- or dl,20h ; set binary mode in device info
- mov dh,0
- mov ah,ioctl
- mov al,1 ; set device info
- int dos
- clc
- ret ; carry clear for success
-
- showkey:mov ax,offset shkmsg
- mov cx,shklen
- ret
-
- ; Initialization for using serial port. Returns normally.
- ; Attempts to put port device in binary mode. [jrd]
- SERINI PROC NEAR
- cmp prthnd,0 ; got a handle yet?
- jne serin0 ; ne = yes, just go on
- push bx
- call opnprt ; else 'open' the port
- pop bx
- jc serin2 ; c = failure
- serin0: push bx
- mov bx,portval ; get port
- mov parmsk,0ffh ; parity mask, assume parity is None
- cmp [bx].parflg,parnon ; is it None?
- je serin1 ; e = yes
- mov parmsk,07fh ; no, pass lower 7 bits as data
- serin1: mov bx,[bx].flowc ; get flow control chars
- mov flowoff,bl ; xoff or null
- mov flowon,bh ; xon or null
- pop bx
- clc ; carry clear for success
- serin2: ret
- SERINI ENDP
-
- ; Reset the serial port. This is the opposite of serini. Calling
- ; this twice without intervening calls to serini should be harmless.
- ; Returns normally.
-
- SERRST PROC NEAR
- clc
- ret
- SERRST ENDP
-
- ; Produce a short beep. The PC DOS bell is long enough to cause a loss
- ; of data at the port. Returns normally.
-
- BEEP PROC NEAR
- mov dl,bell
- mov ah,dconio
- int dos
- clc
- ret
- BEEP ENDP
-
- ; Dumb terminal emulator. Doesn't work too well above 1200 baud (and
- ; even at 1200 baud you sometimes lose the first one or two characters
- ; on a line). Does capture (logging), local echo, debug display, tests
- ; for printer/logging device not ready. Uses keyboard translator
- ; 20 March 1987 [jrd].
- term proc near
- mov argadr,ax ; save argument ptr
- mov si,ax ; this is source
- mov oldsp,sp ; remember stack for i/o failure,
- mov di,offset ourarg ; place to store arguments
- mov ax,ds
- mov es,ax ; address destination segment
- mov cx,size termarg
- cld
- rep movsb ; copy into our arg blk
- mov ax,ourarg.captr
- mov captrtn,ax ; buffer capture routine
- mov parmsk,0ffh ; parity mask, assume parity = None
- cmp ourarg.parity,parnon ; is parity None?
- je term1 ; e = yes, keep all 8 bits
- mov parmsk,07fh ; else keep lower 7 bits
-
- term1: call portchr ; get char from port, apply parity mask
- jnc short term3 ; nc = char
- term2: mov fairness,0 ; say kbd was examined
- call keybd ; call keyboard translator in msu
- jnc term1 ; nc = no char or have processed it
- call pntflsh ; flush printer buffer
- stc
- ret ; carry set = quit connect mode
- term3: and al,parmsk ; apply 8/7 bit parity mask
- call outtty ; print on terminal
- inc fairness ; say read port but not kbd, again
- cmp fairness,200 ; this many port reads before kbd?
- jb term1 ; b = no, read port again
- call pntflsh ; flush printer buffer
- jmp short term2 ; yes, let user have a chance too
- quit: ret
- term endp
-
- ; keyboard translator action routines, system dependent, called from msugen.
- ; These are invoked by a jump instruction. Return carry clear for normal
- ; processing, return carry set exit Connect mode (kbdflg has transfer char).
-
- chrout: call outprt ; put char in al to serial port
- clc ; stay in Connect mode
- ret
-
- trnprs: push ax ; toggle Copy screen to printer
- test anspflg,prtscr ; should we be printing?
- jnz trnpr2 ; nz = yes, its on and going off
- mov ah,ioctl
- mov al,7 ; get output status of printer
- push bx
- mov bx,prnhand ; file handle for system printer
- int dos
- pop bx
- jc trnpr1 ; c = printer not ready
- cmp al,0ffh ; Ready status?
- je trnpr2 ; e = Ready
- trnpr1: call beep ; Not Ready, complain
- jmp short trnpr3 ; and ignore request
- trnpr2: xor anspflg,prtscr ; toggle print flag
- trnpr3: pop ax
- clc
- ret
-
- ; toggle Connect mode status line
- trnmod proc near
- ret
- trnmod endp
-
- klogon proc near ; resume logging (if any)
- test flags.capflg,logses ; session logging enabled?
- jz klogn ; z = no, forget it
- or ourarg.flgs,capt ; turn on capture flag
- klogn: clc
- ret
- klogon endp
-
- klogof proc near ; suspend logging (if any)
- and ourarg.flgs,not capt ; stop capturing
- klogo: clc
- ret
- klogof endp
-
- snull: mov ah,0 ; send a null
- call outchr ; send without echo or logging
- clc
- ret
-
- kdos: mov al,'P' ; Push to DOS
- jmp short cmdcom
- cstatus:mov al,'S' ; these commands exit Connect mode
- jmp short cmdcom
- cquit: mov al,'C'
- jmp short cmdcom
- cquery: mov al,'?'
- jmp short cmdcom
- chang: mov al,'H' ; Hangup, drop DTR & RTS
- ;;; jmp short cmdcom
- cmdcom: mov kbdflg,al ; pass char to msster.asm via kbdflg
- stc ; say exit Connect mode
- ret
- ;; end of action routines
-
- ; put the character in al to the screen, do capture and printing,
- ; does translation for Set Input command.
- ; Adapted from msyibm.asm
- outtty proc near
- test flags.remflg,d8bit ; keep 8 bits for displays?
- jnz outnp8 ; nz = yes, 8 bits if possible
- and al,7fh ; remove high bit
- outnp8: cmp rxtable+256,0 ; is translation off?
- je outnp7 ; e = yes, off
- push bx ; Translate incoming char
- mov bx,offset rxtable ; address of translate table
- xlatb ; new char is in al
- pop bx
- outnp7: test ourarg.flgs,capt ; capturing output? Can be shut off
- jz outnoc ; no, forget this part
- call captrtn ; give it captured character
- outnoc: test anspflg,prtscr ; should we be printing?
- jz outnop ; no, keep going
- call pntchr ; queue char for printer
- jnc outnop ; nc = successful print
- push ax
- call beep ; else make a noise and
- call trnprs ; turn off printing
- pop ax
- outnop: cmp flags.vtflg,0 ; emulating a terminal?
- jnz outnop1 ; nz = yup, go do something smart
- test ourarg.flgs,trnctl ; debug? if so use dos tty mode
- jz outnp4 ; z = no
- mov ah,conout
- cmp al,7fh ; Ascii Del char or greater?
- jb outnp1 ; b = no
- je outnp0 ; e = Del char
- push ax ; save the char
- mov dl,7eh ; output a tilde for 8th bit
- int dos
- pop ax ; restore char
- and al,7fh ; strip high bit
- outnp0: cmp al,7fh ; is char now a DEL?
- jne outnp1 ; ne = no
- and al,3fH ; strip next highest bit (Del --> '?')
- jmp outnp2 ; send, preceded by caret
- outnp1: cmp al,' ' ; control char?
- jae outnp3 ; ae = no
- add al,'A'-1 ; make visible
- outnp2: push ax ; save char
- mov dl,5eh ; caret
- int dos ; display it
- pop ax ; recover the non-printable char
- outnp3: mov dl,al
- int dos
- ret
- outnp4: cmp al,bell ; bell (Control G)?
- jne outnp5 ; ne = no
- jmp beep ; use short beep, avoid char loss
- outnop1:
- outnp5: test flags.remflg,d8bit ; keep 8 bits for displays?
- jnz outnp9 ; nz = yes, 8 bits if possible
- and al,7fh ; remove high bit
- outnp9: mov ah,conout ; dostty screen mode
- mov dl,al ; write without intervention
- int dos ; else let dos display char
- ret ; and return
- outtty endp
-
-
- ; send the character in al out to the serial port; handle echoing.
- ; Can send an 8 bit char while displaying only 7 bits locally.
- outprt proc near
- test ourarg.flgs,lclecho ; echoing?
- jz outpr1 ; z = no, forget it
- push ax ; save char
- call outtty ; print it
- pop ax ; restore
- outpr1: mov ah,al ; outchr expects char in ah
- jmp outchr ; output to the port
- outprt endp
-
- ; Get a char from the serial port manager, return it in al
- ; returns with carry clear if a character is available, else carry set
- portchr proc near
- call prtchr ; character at port?
- jnc portc1 ; nc = yes
- portc0: stc ; carry -> no character
- ret
- portc1: and al,parmsk ; apply 8/7 bit parity mask
- or al,al ; catch nulls
- jz portc0 ; z = null, ignore it
- cmp al,del ; catch dels
- je portc0 ; e = del, ignore it
- portc2: clc ; have a character, in AL
- ret
- portchr endp
-
- ; Invoked by keyboard translator when an unknown keyboard verb is used as
- ; a string definition, such as {\ktest}. Enter with vtmacname pointing to
- ; uppercased verb name, asciiz, and vtmaclen set to its length.
- extmacro proc near
- call dword ptr vtmacroptr ; FAR pointer
- ret
- extmacro endp
-
- fdec2di proc far
- call dec2di
- ret
- fdec2di endp
- code ends
-
- code1 segment
- assume cs:code1
-
-
- ;
- ; Reference Macro structure for db number of entries (mac names)
- ; is file table mcctab |-> dw length of macroname
- ; mssset.asm each entry |-> db 'macroname'
- ; where these |-> dw segment:0 of definition string
- ; are stored. (offset part is always 0)
- ; Definition string in db length of <string with null>
- ; buffer macbuf db 'string with trailing null'
- ;
- vtmacro proc far ; common code for external macro
- push bx
- push cx
- push si
- push di
- push es
- mov ax,ds
- mov es,ax
- mov di,offset rdbuf+2 ; macro def buffer starts here
- mov si,vtmacname ; pointer to macro name
- mov cx,vtmaclen ; length of macro name<sp/null>text
- mov [di-2],cx ; counted string field
- cld
- rep movsb ; copy to rdbuf
- mov byte ptr [di],0 ; null terminator
- mov si,offset rdbuf+2 ; look for name-text separator
- mov cx,vtmaclen
- vtmac1: lodsb
- cmp al,' ' ; space separator?
- je vtmac1a ; e = yes, stop here
- or al,al ; null terminator?
- jz vtmac1a ; e = yes, stop here
- loop vtmac1
- inc si ; to do null length correctly
- vtmac1a:sub si,offset rdbuf+2+1 ; compute length of macro name
- mov cx,si
- mov vtmaclen,cx ; save a macro name length
- ; check for existence of macro
- mov bx,offset mcctab ; table of macro names
- mov cl,[bx] ; number of names in table
- xor ch,ch
- jcxz vtmacx ; z = empty table, do nothing
- inc bx ; point to length of first name
- vtmac2: mov ax,[bx] ; length of this name
- cmp ax,vtmaclen ; length same as desired keyword?
- jne vtmac3 ; ne = no, search again
- mov si,bx
- add si,2 ; point at first char of name
- push cx ; save name counter
- push di ; save reg
- mov cx,vtmaclen ; length of name
- mov di,vtmacname ; point at desired macro name
- push es ; save reg
- push ds
- pop es ; make es use data segment
- cld
- repe cmpsb ; match strings
- pop es ; need current si below
- pop cx
- pop di ; recover saved regs
- je vtmac4 ; e = matched
- vtmac3: add bx,ax ; step to next name, add name length
- add bx,4 ; + count and def word ptr
- loop vtmac2 ; try next name
- vtmacx: pop es
- pop di
- pop si ; no macro, return to Connect mode
- pop cx
- pop bx
- ret
-
- vtmac4: cmp taklev,maxtak ; room in Take level?
- jge vtmacx ; ge = no, exit with no action
- inc taklev ; increment take level
- add takadr,size takinfo ; make a new Take entry/macro
- mov bx,takadr ; point to current macro structure
- mov ax,ds ; segment of rdbuf
- mov [bx].takbuf,ax ; segment of definition string struc
- mov cx,word ptr rdbuf ; length of count + string
- mov [bx].takcnt,cx ; number of chars in definition
- mov [bx].takargc,0 ; our argument count
- mov [bx].takptr,offset rdbuf+2 ; where to read next command char
- mov [bx].taktyp,0ffh ; flag as a macro
- pop es
- pop di
- pop si
- pop cx
- pop bx
- jmp dword ptr endconptr ; exit Connect mode
- vtmacro endp
- code1 ends
-
- code segment
- assume cs:code
-
- ; Error recovery routine used when outchr reports unable to send character
- ; or when vtmacro requests exiting Connect mode.
- ; Exit Connect mode cleanly, despite layers of intermediate calls.
- endcon proc near
- mov kbdflg,'C' ; report 'C' to TERM's caller
- mov sp,oldsp ; recover startup stack pointer
- ; TERM caller's return address is now
- ; on the top of stack. A longjmp.
- jmp quit ; exit Connect mode cleanly
- endcon endp
-
- ; Service SET NETBIOS-NAME name command at Kermit prompt level
- setnbios proc near
- ret
- setnbios endp
- sesdisp proc near
- ret
- sesdisp endp
-
- code ends
- end
-